package com.crm.common.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.PutObjectRequest;
import lombok.Data;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.UUID;

/**
 * Oss服务调用
 */
@Log4j2
@Configuration
@ConfigurationProperties(prefix = "oss")
@Data
public class OssUtil {
	@Value("${aliyun.oss.endpoint}")
	private String endpoint;
	@Value("${aliyun.oss.accessId}")
	private String accessKeyId;
	@Value("${aliyun.oss.accessKey}")
	private String accessKeySecret;
	@Value("${aliyun.oss.bucket}")
	private String bucketName;

	/**
	 * 构建 OSS 对象
	 * @return
	 */
	private OSS initOssClient() {
		return new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
	}


	/**
	 * 默认路径上传本地文件
	 *
	 * @param filePath
	 */
	public String uploadFile(String filePath) {
		return uploadFileForBucket(bucketName, getOssFilePath(filePath), filePath);
	}

	/**
	 * 默认路径上传multipartFile文件
	 *
	 * @param multipartFile
	 */
	public String uploadMultipartFile(MultipartFile multipartFile) {
		return uploadMultipartFile(bucketName, getOssFilePath(Objects.requireNonNull(multipartFile.getOriginalFilename())), multipartFile);
	}

	/**
	 * 上传 multipartFile 类型文件
	 *
	 * @param bucketName
	 * @param ossPath
	 * @param multipartFile
	 */
	public String uploadMultipartFile(String bucketName, String ossPath, MultipartFile multipartFile) {
		InputStream inputStream = null;
		try {
			inputStream = multipartFile.getInputStream();
		} catch (IOException e) {
			e.printStackTrace();
		}
		uploadFileInputStreamForBucket(bucketName, ossPath, inputStream);
		return  ossPath;
	}

	/**
	 * 使用File上传PutObject上传文件 ** 程序默认使用次方法上传
	 * @param bucketName 实例名称
	 * @param ossPath    oss存储路径
	 * @param filePath   本地文件路径
	 */
	public String uploadFileForBucket(String bucketName, String ossPath, String filePath) {
		// 创建PutObjectRequest对象。
		PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, ossPath, new File(filePath));

		// 上传
		initOssClient().putObject(putObjectRequest);
		return  ossPath;
	}

	/**
	 * 使用文件流上传到指定的bucket实例
	 *
	 * @param bucketName 实例名称
	 * @param ossPath    oss存储路径
	 * @param filePath   本地文件路径
	 */
	public String uploadFileInputStreamForBucket(String bucketName, String ossPath, String filePath) {

		// 填写本地文件的完整路径。如果未指定本地路径，则默认从示例程序所属项目对应本地路径中上传文件流。
		InputStream inputStream = null;
		try {
			inputStream = new FileInputStream(filePath);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		// 填写Bucket名称和Object完整路径。Object完整路径中不能包含Bucket名称。
		uploadFileInputStreamForBucket(bucketName, ossPath, inputStream);
		return ossPath;
	}

	public void uploadFileInputStreamForBucket(String bucketName, String ossPath, InputStream inputStream) {
		initOssClient().putObject(bucketName, ossPath, inputStream);
	}

	/**
	 * 下载
	 *
	 * @param ossFilePath
	 * @param filePath
	 */
	public void downloadFile(String ossFilePath, String filePath) {
		downloadFileForBucket(bucketName, ossFilePath, filePath);
	}

	/**
	 * 下载
	 *
	 * @param bucketName  实例名称
	 * @param ossFilePath oss存储路径
	 * @param filePath    本地文件路径
	 */
	public void downloadFileForBucket(String bucketName, String ossFilePath, String filePath) {
		initOssClient().getObject(new GetObjectRequest(bucketName, ossFilePath), new File(filePath));
	}

	/**
	 * @return
	 */
	public String getOssDefaultPath() {
		LocalDateTime now = LocalDateTime.now();
		return now.getYear() + "/" +
						now.getMonth() + "/" +
						now.getDayOfMonth() + "/" +
						now.getHour() + "/" +
						now.getMinute() + "/";
	}

	/**
	 * 对文件进行重新命名
	 *
	 * @param filePath
	 * @return
	 */
	public String getOssFilePath(String filePath) {
		String fileSuf = filePath.substring(filePath.lastIndexOf(".") + 1);
		return getOssDefaultPath() + UUID.randomUUID().toString() + "." + fileSuf;
	}

}
